/**
 * General game loop and timing code abstracted in a Singleton/Manager object with a interface API
 * @namespace: Arena
 * @class: Arena.GameLoopManager
 **/
(function(){
    Arena.GameLoopManager = function(){
        Arena.GameLoopManager.superclass.constructor.call(this);
    };

    extend(Arena.GameLoopManager, Game.GameLoopManager,
    {
       lastTime: 0,
       gameTick: null,
       prevElapsed: 0,
       prevElapsed2: 0,

       run: function run(gameTick){
            var prevTick = this.gameTick;
           this.gameTick = gameTick;
           if(this.lastTime == 0){
               // Once started, the loop never stops.
               // But this function is called to change tick functions.
               var bind = this;
               requestAnimFrame(function(){bind.tick();});
               this.lastTime = 0;
           }
       },

       stop: function stop(){
            this.run(null);
       },

       tick: function tick(){
           if(this.gameTick != null){
                var bind = this;
                requestAnimFrame(function(){bind.tick();});
           }else{
                this.lastTime = 0;
                return;
           }
           var timeNow = Date.now();
           var elapsed = timeNow - this.lastTime;
           if(elapsed > 0){
               if(this.lastTime != 0){
                   // Cap max elapsed time to 1 second to avoid death spiral
                   if(elapsed > 1000){
                       elapsed = 1000;
                   }
                   // hack fps smoothing
                   var smoothElapsed = (elapsed + this.prevElapsed + this.prevElapsed2)/3;
                   this.gameTick(0.001*smoothElapsed);
                   this.prevElapsed2 = this.prevElapsed;
                   this.prevElapsed = elapsed;
               }
               this.lastTime = timeNow;
           }
       }
    });
})();